//||=========================================================================||
//||                                                                         ||
//||                            FastComplex.cpp                              ||
//||                                                                         ||
//||                           by the_best_goose))                           ||
//||                                                                         ||
//||=========================================================================||

#include "FastComplex.h"

//-----------------------------------------------------------------------------

my_inline FastComplex::FastComplex():
re(0.0f),
im(0.0f)
{
}

//-------------------------------------------------------------------------

my_inline FastComplex::FastComplex(const float re, const float im):
re(re),
im(im)
{
}

//-------------------------------------------------------------------------

my_inline FastComplex::FastComplex(const float re):
re(re),
im(0.0f)
{
}

//-------------------------------------------------------------------------

my_inline void FastComplex::Null()
{
	re = im = 0.0f;
}

//-------------------------------------------------------------------------

my_inline const FastComplex& FastComplex::operator=(const FastComplex& c)
{
	re = c.re;
	im = c.im;
	return(*this);
}

//-------------------------------------------------------------------------

my_inline FastComplex FastComplex::operator+(const FastComplex& c)
{
	return FastComplex(c.re + re, c.im + im);
}

//-------------------------------------------------------------------------

my_inline FastComplex FastComplex::operator-(const FastComplex& c)
{
	return FastComplex(re - c.re, im - c.im);
}

//-------------------------------------------------------------------------

my_inline FastComplex FastComplex::operator*(const FastComplex& c)
{
	return FastComplex(c.re * re - c.im * im, c.im * re + c.re * im);
}

//-------------------------------------------------------------------------

my_inline FastComplex FastComplex::operator*(const float& c)
{
	return FastComplex(re * c, im * c);
}

//-------------------------------------------------------------------------

my_inline FastComplex FastComplex::operator/(const FastComplex& c)
{
	return FastComplex(re / c.re, im / c.im);
}

//-------------------------------------------------------------------------

my_inline FastComplex operator*(const float& d, const FastComplex& c)
{
	return FastComplex(d * c.re, d * c.im);
}

//-------------------------------------------------------------------------

my_inline FastComplex operator+(const float& d, const FastComplex& c)
{
	return FastComplex(d + c.re, c.im);
}

//-------------------------------------------------------------------------

my_inline FastComplex operator-(const float& d, const FastComplex& c)
{
	return FastComplex(d - c.re, - c.im);
}

my_inline FastComplex pow(const FastComplex& c, const int num)
{
	switch(num)
	{
		case 1:
			return c;
		case 2:
			return FastComplex(c.re * c.re - c.im * c.im, 2 * c.re * c.im);
		case 3:
			return FastComplex(c.re * c.re * c.re - 3 * c.re * c.im * c.im,
					           3 * c.im * c.re * c.re - c.im * c.im * c.im);
		case 4:
			return FastComplex(c.re * c.re * c.re * c.re +
					           c.im * c.im * c.im * c.im -
					           6 * c.re * c.re * c.im * c.im,
							   4 * c.re * c.re * c.re * c.im -
							   4 * c.re * c.im * c.im * c.im);
		case 5:
			return FastComplex(c.re * c.re * c.re * c.re * c.re -
					           10 * c.re * c.re * c.re * c.im * c.im +
							   5 * c.re * c.im * c.im * c.im * c.im,
							   5 * c.re * c.re * c.re * c.re * c.im -
							   10 * c.re * c.re * c.im * c.im * c.im +
							   c.im * c.im * c.im * c.im * c.im);
	}
	FastComplex ans = c;
	for(int i = num; i > 1; --i)
	{
		ans = ans * c;
	}
	return ans;
}

